package com.yatuhashi.encrypt;

import java.io.File;
import java.io.FileInputStream;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.yatuhashi.encrypt.adapter.BaseAdapter;
import com.yatuhashi.encrypt.common.Encrypt;
import com.yatuhashi.encrypt.common.FileUtil;
import com.yatuhashi.encrypt.common.Util;

public class EncryptActivity extends Activity implements OnClickListener {
	private String masterPath;
	private String inputPath;
	private String outputPath;
	
	private File masterDir;
	private File inputDir;
	private File outputDir;
	
	private String selectedFileName;
	
	private LinearLayout logLayout;
	private SharedPreferences pref;
	private static final String PREF_KEY = "password";
	private String lastPassWord;
	private TextView selectedView;
	private EditText inputBox;
	private Button encryptBtn;
	private Button folderListBtn;
	private TextView singleLogTextView;
	private AlertDialog alertDialog;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // 親フォルダの作成
        masterPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/encode";
        masterDir = new File(masterPath);
        if(!masterDir.exists()) {
        	masterDir.mkdirs();
        }
        
        // 暗号化前のファイルを格納するフォルダの作成
        inputPath = masterPath+"/input";
        inputDir = new File(inputPath);
        if(!inputDir.exists()) {
        	inputDir.mkdirs();
        }
        
        // 暗号化後のファイルを格納するフォルダの作成
        outputPath = masterPath+"/output";
        outputDir = new File(outputPath);
        if(!outputDir.exists()) {
        	outputDir.mkdirs();
        }
        
        selectedView = (TextView) findViewById(R.id.selected_folder);
        folderListBtn = (Button) findViewById(R.id.folder_list);
        inputBox = (EditText) findViewById(R.id.password);
        encryptBtn = (Button) findViewById(R.id.encrypt);
        logLayout = (LinearLayout) findViewById(R.id.log_list);
        
        pref = getPreferences(MODE_PRIVATE);
        lastPassWord = pref.getString(PREF_KEY, null);
        if(lastPassWord!=null) {
        	inputBox.setHint(lastPassWord);
        }
        
        folderListBtn.setOnClickListener(this);
        encryptBtn.setOnClickListener(this);
    }
    
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.folder_list:
			showFolderList();
			break;
		case R.id.encrypt:
			doEncrypt();
			break;
		default:
			break;
		}
	}
	
	private void showFolderList() {
		BaseAdapter adapter = new BaseAdapter(this);
		File[] folder = inputDir.listFiles();
		for(File file : folder) {
			adapter.add(file.getName());
		}
		
		AlertDialog.Builder ad = new AlertDialog.Builder(this);
		LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
		View view = inflater.inflate(R.layout.folder_list_dialog, null);
		ListView listView = (ListView) view.findViewById(R.id.list);
		listView.setAdapter(adapter);
		listView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position,
					long id) {
				setAndDo(parent.getAdapter().getItem(position).toString());
				alertDialog.dismiss();
			}
		});
		
		ad.setView(view);
		alertDialog = ad.create();
		alertDialog.show();
	}
	
	private void setAndDo(String path) {
		File idir = new File(inputPath+"/"+path);
		File odir = new File(outputPath+"/"+path);
		
		if(!idir.exists()) {
			idir.mkdirs();
		}
		if(!odir.exists()) {
			odir.mkdirs();
		}
		
		selectedFileName = path;
		selectedView.setText(path);
		selectedView.setVisibility(View.VISIBLE);
	}
	
	private void doEncrypt() {
		if(selectedFileName==null) {
			toast("フォルダを選択してください。");
			return;
		}
		
		lastPassWord = inputBox.getText().toString();
        SharedPreferences.Editor editor = pref.edit();
        editor.putString(PREF_KEY, lastPassWord);
        editor.commit();
		
        final ProgressDialog dialog = new ProgressDialog(this);
        dialog.setCancelable(false);
        dialog.setMessage("暗号化中...");
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.show();
        
        final Handler handler = new Handler();
    	final Handler handler2 = new Handler();
        Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				File files = new File(inputPath+"/"+selectedFileName);
		        File[] fileList = files.listFiles();
		        for(File file : fileList) {
		        	final String fileName = file.getName();
		        	try {
						byte[] encrypted = Encrypt.encode(lastPassWord, Util.getBytes(new FileInputStream(file)));
						FileUtil.write(outputPath+"/"+selectedFileName+"/"+file.getName(), encrypted);
				    	handler2.post(new Runnable() {
							@Override
							public void run() {
								addLog(outputPath+"/"+selectedFileName+"/"+fileName, true);
							}
				    	});
					} catch (Exception e) {
				    	handler2.post(new Runnable() {
							@Override
							public void run() {
								addLog(outputPath+"/"+selectedFileName+"/"+fileName, false);
							}
				    	});
					}
		        }
		        
		        handler.post(new Runnable() {
					@Override
					public void run() {
						dialog.dismiss();
						toast("暗号化が完了しました");
					}
				});
			}
		});
        thread.start();
	}
	
	private void toast(String message) {
		Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
	}
	
    /**
     * ログ出力を行う
     * @param logText
     */
    private void addLog(final String logText, final boolean success) {
    	singleLogTextView = new TextView(EncryptActivity.this);
    	if(success) {
    		singleLogTextView.setText("OK:"+logText);
    		singleLogTextView.setTextColor(Color.GREEN);
    	} else {
    		singleLogTextView.setText("NG:"+logText);
    		singleLogTextView.setTextColor(Color.RED);
    	}
    	logLayout.addView(singleLogTextView);
    }
}